#include <iostream>

#if 0
    class Base1
    {
    public:
        Base1(int a):a(a){std::cout<<"Base1\n";}
        void show()
        {
            std::cout<<"a:"<<a<<std::endl;
        }
    protected:
        int a;
    };

    class Base2
    {
    public:
        Base2(int b):b(b){std::cout<<"Base2\n";}
        void show()
        {
            std::cout<<"b:"<<b<<std::endl;
        }
    protected:
        int b;
    };

    class Derived
    {
    public:
        Derived(int a, int b):b1(a), b2(b){}
        void show()
        {
            b1.show();
            b2.show();
        }
    private:
        // 所谓组合就是把要使用的类的对象塞到类里面
        Base1 b1;
        Base2 b2;
    };

    int main()
    {
        Derived d(1, 2);
        d.show();
        return 0;
    }
#endif

#if 1
    class Base1
    {
    public:
        explicit Base1(int a):a(a){std::cout<<"Base1\n";}
        void show()
        {
            std::cout<<"a:"<<a<<std::endl;
        }
    protected:
        int a;
    };

    class Base2
    {
    public:
        Base2(int b):b(b){std::cout<<"Base2\n";}
        void add()
        {
            b++;
        }
        void show()
        {
            std::cout<<"b:"<<b<<std::endl;
        }
    protected:
        int b;
    };

    // 用组合的目的是不想用多继承，但不代表不用继承
    // 那就折中一下，一半组合，一半继承
    class Derived:public Base2 // 一半继承
    {
    public:
        Derived(int a, int b):b1(a), Base2(b){} // b1是变量赋值，Base2是调用父类的构造函数
        // 组合的弊病就是：现成的函数不能用，得再多封一层，因为里面的成员变量是private的，想用它的函数得再多套一层外壳，不是直接调的它的函数，而是接它的对象去调，外面再套一层函数，把它封起来，这种写法比较繁琐
        // 相当于要多封一层接口
        // void add()
        // {
        //     b2.add();
        // }
        void show()
        {
            b1.show();
            Base2::show();
        }
    private:
        // 所谓组合就是把要使用的类的对象塞到类里面
        // 但是成员变量是私有权限
        Base1 b1; // 一半组合
    };

    int main()
    {
        Derived d(1, 2);
        d.add();
        d.show();
        return 0;
    }
#endif